package com.blazemina.mina.acceptor;

import java.io.IOException;
import java.net.InetSocketAddress;
import java.net.SocketAddress;

import org.apache.mina.core.service.IoAcceptor;
import org.apache.mina.core.service.IoHandler;
import org.apache.mina.filter.codec.ProtocolCodecFactory;
import org.apache.mina.filter.codec.ProtocolCodecFilter;
import org.apache.mina.transport.socket.SocketSessionConfig;
import org.apache.mina.transport.socket.nio.NioSocketAcceptor;

import com.blazegame.logging.Logger;
import com.blazegame.logging.LoggerFactory;
import com.blazemina.config.BlazeminaConfigManager;
import com.blazemina.exception.InitializationException;
import com.blazemina.message.Message;
import com.blazemina.mina.Connector;
import com.blazemina.mina.config.SocketOption;
import com.blazemina.mina.protocol.amf.AmfCodecFactory;
import com.blazemina.util.ClassUtils;

/**
 * 服务器入口类
 * 
 * @author JackChu
 * @version 1.0.0 2012-1-11 下午8:05:30
 */
public class AbstractAcceptor implements Connector {

	private static final Logger log = LoggerFactory
			.getLogger(AbstractAcceptor.class);

	private IoAcceptor acceptor;

	private SocketOption socketOption;

	/**
	 * 用户自定义初始化
	 */
	public void init() {
		socketOption = BlazeminaConfigManager.me().getSocketOption();

	}

	/**
	 * 服务器启动
	 */
	public void start() {

		int socketThreads = socketOption.getIoThread();

		acceptor = new NioSocketAcceptor(socketThreads);

		SocketSessionConfig socketSessionConfig = (SocketSessionConfig) acceptor
				.getSessionConfig();

		if (socketOption.isHasSocketReceiveBuffer()) {
			int receiveBufferSize = socketOption.getSocketReceiveBuffer();
			socketSessionConfig.setReceiveBufferSize(receiveBufferSize);
		}
		if (socketOption.isHasSocketSendBuffer()) {
			int sendBufferSize = socketOption.getSocketSendBuffer();
			socketSessionConfig.setSendBufferSize(sendBufferSize);
		}
		if (socketOption.isHasKeepAlive()) {
			socketSessionConfig.setKeepAlive(socketOption.isKeepAlive());
		}
		if (socketOption.isHasTcpNoDelay()) {
			socketSessionConfig.setTcpNoDelay(socketOption.isTcpNoDelay());
		}

		if (socketOption.isHasBothIdleTimeSeconds()) {
			socketSessionConfig.setBothIdleTime(socketOption
					.getBothIdleTimeSeconds());
		} else if (socketOption.isHasReadIdleTimeSeconds()) {
			socketSessionConfig.setReaderIdleTime(socketOption
					.getReadIdleTimeSeconds());
		} else if (socketOption.isHasWriteIdleTimeSeconds()) {
			socketSessionConfig.setWriterIdleTime(socketOption
					.getWriteIdleTimeSeconds());
		}
		String codecFactory = socketOption.getCodecFactory();
		ProtocolCodecFactory protocolCodecFactory = null;
		if (codecFactory != null) {
			protocolCodecFactory = (ProtocolCodecFactory) ClassUtils
					.getApplicationInstance(codecFactory);
		} else {
			protocolCodecFactory = new AmfCodecFactory();
		}
		acceptor.getFilterChain().addLast("codec",
				new ProtocolCodecFilter(protocolCodecFactory));
		IoHandler ioHandler = BlazeminaConfigManager.me().getRequestHandler();
		if(ioHandler == null){
			throw new InitializationException("server handler is initialize?");
		}
		acceptor.setHandler(ioHandler);
		bind(acceptor);
	}

	private void bind(IoAcceptor acceptor) {
		String host = socketOption.getHost();

		int port = socketOption.getPort();
		if (port == 0) {
			throw new InitializationException("sokcet port is initialize?");
		}
		SocketAddress address = new InetSocketAddress(port);
		if (host != null) {
			address = new InetSocketAddress(host, port);
		}
		try {
			acceptor.bind(address);
		} catch (IOException e) {
			log.error("io acceptor start error", e);
		}

		log.debug("Acceptor has Started,host:#1,port:#2",
				host == null ? "localhost" : host, "" + port);

	}

	public void stop() {
		if (acceptor != null) {
			acceptor.unbind();
			acceptor.dispose();
		}
		log.debug("Acceptor has stoped!!");
	}

	/* (non-Javadoc)
	 * @see com.blazemina.mina.Connector#send(com.blazemina.message.Message)
	 */
	@Override
	public void send(Message message) {
		// TODO Auto-generated method stub
		
	}

}
